<!--author: lms-->

<script>

import RBootTableSetting from './components/RBootTableSetting'

export default {
  name: 'RBootTable',
  render: function(createElement) {
    const that = this

    // 表格节点
    const tableNode = createElement(
      'el-table', {
        ref: 'slotRef',
        props: {
          height: this.table.height,
          data: this.data
        },
        key: this.table.key,
        attrs: this._deepClone(this.$attrs),
        on: this._deepClone(this.$listeners)
      },
      this.columnList
    )

    // 设置按钮节点
    const settingNode = createElement(
      'div', {
        class: 'r-boot-table-setting rotate',
        style: {
          height: this.footerHeight + 'px',
          bottom: '-' + this.footerHeight + 'px'

        },
        on: {
          click() {
            that.ifSettingDialog = true
          }
        }
      },
      [
        createElement('i', {
          class: 'el-icon-setting',
          style: {
            'line-height': this.footerHeight + 'px'
          }
        })
      ]
    )

    // 设置弹框节点
    const dialogNode = createElement(
      RBootTableSetting, {
        props: {
          elementList: this.$slots.default,
          ifOpen: this.ifSettingDialog,
          ifCache: this.ifCache,
          closeRef() {
            that.ifSettingDialog = false
          },
          syncRef(settingList) {
            that._rerender(settingList)
          }
        }
      },
      [
        createElement('i', {
          class: 'el-icon-setting'
        })
      ]
    )

    return createElement(
      'div', {
        class: 'r-boot-table-body'
      },
      [tableNode, settingNode, dialogNode]
    )
  },
  components: {
    RBootTableSetting
  },
  data() {
    return {
      // 原始表格的列结构
      elementList: [],

      // 展示表格的列结构
      columnList: [],

      /**
       * 表格指示器
       */
      table: {
        // 刷新表格用的
        key: Math.random(),
        // 表格高度
        height: 600
      },

      /**
       * 配置弹窗的开关
       */
      ifSettingDialog: false
    }
  },
  props: {
    // 表格数据
    data: {
      type: Array,
      required: true
    },
    // 表格是否贴底
    ifStick: {
      type: Boolean,
      default: true
    },
    // 表格配置是否缓存
    ifCache: {
      type: Boolean,
      default: true
    },
    // 底部高度
    footerHeight: {
      type: Number,
      default: 10
    },
  },
  mounted() {
    this._resize()
    this._monitor()
  },
  activated() {
    this._resize()
  },
  methods: {
    _rerender(settingList) {
      const columnList = []
      for (let setting of settingList) {
        const column = { ...setting.element }
        column.componentOptions.propsData.fixed = setting.fixed
        setting.ifShow && columnList.push(column)
      }
      this.columnList = columnList
      this.table.key = Math.random()
    },
    /**
     * 监听resize
     */
    _monitor() {
      // 附加resize事件
      window.addEventListener('resize', this._resize)

      // 监听组件，当组件的高发生变化时，重绘表格
      new MutationObserver((mutationsList) => {
        const mutation = mutationsList.find((mutation) => {
          return (
            mutation.type === 'attributes' &&
            (mutation.attributeName === 'height' ||
              mutation.attributeName === 'data')
          )
        })
        mutation && this._resize()
      }).observe(this.$el, { attributes: true, childList: false, subtree: false })
    },
    /**
     * 自动表格贴底
     * @private
     */
    _resize() {
      if(this.ifStick) {
        let offsetTop = this.$el['offsetTop']
        let innerHeight = window.innerHeight
        this.table.height = (innerHeight - offsetTop - this.footerHeight) + 'px'
      }
    },
    _deepClone(target) {
      // 定义一个变量
      let result
      // 如果当前需要深拷贝的是一个对象的话
      if (typeof target === 'object') {
        // 如果是一个数组的话
        if (Array.isArray(target)) {
          result = [] // 将result赋值为一个数组，并且执行遍历
          for (let i in target) {
            // 递归克隆数组中的每一项
            result.push(this._deepClone(target[i]))
          }
          // 判断如果当前的值是null的话；直接赋值为null
        } else if (target === null) {
          result = null
          // 判断如果当前的值是一个RegExp对象的话，直接赋值
        } else if (target.constructor === RegExp) {
          result = target
        } else {
          // 否则是普通对象，直接for in循环，递归赋值对象的所有值
          result = {}
          for (let i in target) {
            result[i] = this._deepClone(target[i])
          }
        }
        // 如果不是对象的话，就是基本数据类型，那么直接赋值
      } else {
        result = target
      }
      // 返回最终结果
      return result
    }
  }
}
</script>

<style lang="scss" scoped>
.r-boot-table-body {
  position: relative;
}

.r-boot-table-setting {
  position: absolute;
  right: 0;
  cursor: pointer;
  width: 48px;
  text-align: center;
}

.rotate {
  -webkit-transition: -webkit-transform 2s;

  &:hover {
    -webkit-transform: rotate(360deg);
  }
}
</style>
